package com.fandou.speech.asr.baidu;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;

import com.baidu.aip.asrwakeup3.core.recog.IStatus;
import com.baidu.aip.asrwakeup3.core.recog.listener.MessageStatusRecogListener;
import com.baidu.speech.asr.SpeechConstant;

import java.util.HashMap;
import java.util.Map;

/**
 * 识别的基类Activity。 ActivityCommon定义了通用的UI部分
 * 封装了识别的大部分逻辑，包括MyRecognizer的初始化，资源释放
 * <p>
 * <p>
 * 集成流程代码，只需要一句： myRecognizer.start(params);具体示例代码参见startRough()
 * =》.实例化 myRecognizer   new MyRecognizer(this, listener);
 * =》 实例化 listener  new MessageStatusRecogListener(null);
 * </p>
 * 集成文档： http://ai.baidu.com/docs#/ASR-Android-SDK/top 集成指南一节
 * demo目录下doc_integration_DOCUMENT
 * ASR-INTEGRATION-helloworld  ASR集成指南-集成到helloworld中 对应 ActivityMiniRecog
 * ASR-INTEGRATION-TTS-DEMO ASR集成指南-集成到合成DEMO中 对应 ActivityUiRecog
 * <p>
 * 大致流程为
 * 1. 实例化MyRecognizer ,调用release方法前不可以实例化第二个。参数中需要开发者自行填写语音识别事件的回调类，实现开发者自身的业务逻辑
 * 2. 如果使用离线命令词功能，需要调用loadOfflineEngine。在线功能不需要。
 * 3. 根据识别的参数文档，或者demo中测试出的参数，组成json格式的字符串。调用 start 方法
 * 4. 在合适的时候，调用release释放资源。
 * <p>
 */

public abstract class AbstractRecognizer implements IStatus {
    protected Context context;

    /**
     * 控制UI按钮的状态
     */
    protected int status;

    /**
     * 日志使用
     */
    private static final String TAG = "AbstractRecognizer";

    private String APP_ID;
    private String APP_KEY;
    private String SECRET_KEY;


    /**
     * 开始录音，点击“开始”按钮后调用。
     */
    protected abstract void start(Map<String, Object> params, MessageStatusRecogListener.OnAsrListener onAsrListener);


    /**
     * 开始录音后，手动停止录音。SDK会识别在此过程中的录音。点击“停止”按钮后调用。
     */
    protected abstract void stop();

    /**
     * 开始录音后，取消这次录音。SDK会取消本次识别，回到原始状态。点击“取消”按钮后调用。
     */
    protected abstract void cancel();

    protected boolean running = false;

    public AbstractRecognizer(Context context) {
        this.context = context;
//        apiParams = new OfflineRecogParams();
//        apiParams = new OnlineRecogParams();
//        apiParams = new NluRecogParams();
//        apiParams = new AllRecogParams();
    }

    protected Map<String, Object> fetchParams(int pid, String outFile) {
        Map<String, Object> params = new HashMap<>();

        params.put(SpeechConstant.ACCEPT_AUDIO_VOLUME, true);  // 音量回调

        //ACCEPT_AUDIO_DATA	boolean	全部	高级	是否需要语音音频数据回调，开启后有CALLBACK_EVENT_ASR_AUDIO事件
        params.put(SpeechConstant.ACCEPT_AUDIO_DATA, true);

		/*
		PID	语言	模型	是否有标点	在线语义	备注
		1536	普通话	搜索模型	无标点	不支持	默认PID
		15361	普通话	搜索模型	无标点	支持
		1537	普通话	输入法模型	可以有标点	不支持
		1736	英语	搜索模型	无标点	不支持
		1737	英语	输入法模型	可以有标点	不支持
		1636	粤语	搜索模型	无标点	不支持
		1637	粤语	输入法模型	可以有标点	不支持
		1836	四川话	搜索模型	无标点	不支持
		1837	四川话	输入法模型	可以有标点	不支持
		1936	普通话	远场模型	有标点	不支持
		19361	普通话	远场模型	有标点	支持
		 */
        params.put(SpeechConstant.PID, pid);

        // OUT_FILE	String ：文件路径	全部	高级	保存识别过程产生的录音文件, 该参数需要开启ACCEPT_AUDIO_DATA后生效
        params.put(SpeechConstant.OUT_FILE, outFile);

        params.put(SpeechConstant.APP_ID, APP_ID);
        params.put(SpeechConstant.APP_KEY, APP_KEY);
        params.put(SpeechConstant.SECRET, SECRET_KEY);

        return params;
    }

    protected void initialAsr(Context context) {
//        apiParams.initSamplePath(context);
        fetchKey(context);
    }

    private void fetchKey(Context context) {
        Bundle metaData;
        try {
            metaData = context.getPackageManager().getApplicationInfo(context.getPackageName(),
                    PackageManager.GET_META_DATA).metaData;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return;
        }

        if (metaData == null) {
            return;
        }

        APP_ID = Integer.toString(metaData.getInt("com.baidu.speech.APP_ID", 0));
        APP_KEY = metaData.getString("com.baidu.speech.API_KEY", "");
        SECRET_KEY = metaData.getString("com.baidu.speech.SECRET_KEY", "");

    }

}
